import * as BabelCore from '@babel/core'
import * as types from '@babel/types'
import { NodePath } from '@babel/traverse'
import { getAuthContent } from './getAuthContent'
import { getAuthName, getRequestName } from './getAuthName'

export const complier = (babel: typeof BabelCore) => {
  const { types: t, template } = babel
  // 模板
  const assignmentBuilder = template('export const NAME = VALUE')
  const requestFuncBuilder = template(`export const FUNCNAME = requestify({
    url: URL,
    params,
    request: REQUEST
  })`)

  // 存储 定义过的变量
  let identify2ValArr: Record<string, any> = {}

  return {
    name: 'bossAuthComplete',
    visitor: {
      Program: {
        enter() {
          identify2ValArr = {}
        },
        exit(path: NodePath<types.Program>) {
          let allBodyNode = path.get('body') || []
          let lastIndex = allBodyNode.length || 0

          let createdAuthNode: Array<types.Node> = []
          let createdRequestNode: Array<types.Node> = []
          for (let key of Object.keys(identify2ValArr)) {
            let authName = getAuthName(key)
            let authContent = getAuthContent(identify2ValArr[key])
            let apiName = getRequestName(key)

            if (apiName) {
              // 构建 请求代码
              // t.identifier(key) 是个变量
              // key 仅仅是个字符串
              createdRequestNode.push(
                requestFuncBuilder({
                  FUNCNAME: apiName,
                  URL: t.identifier(key),
                  REQUEST: t.identifier(key.includes('post') ? 'g.post' : 'g.get')
                }) as types.Node
              )
            }

            // 不是所有得请求 都有权限配置
            if (authName && authContent) {
              createdAuthNode.push(
                assignmentBuilder({
                  NAME: t.identifier(authName),
                  VALUE: authContent
                }) as types.Node
              )
            }
          }

          // 插入 新构造的节点
          let lastNodeItem = path.get(`body.${lastIndex - 1}`)
          if (!Array.isArray(lastNodeItem)) {
            lastNodeItem.insertAfter([...createdAuthNode, ...createdRequestNode])
            // 删除之前的节点
            for (let i = 0; i < lastIndex; i++) {
              let currentFirstNodeItem = path.get(`body.${0}`)
              if (!Array.isArray(currentFirstNodeItem)) {
                currentFirstNodeItem.remove()
              }
            }
          }
        }
      },
      VariableDeclaration(path: NodePath<types.VariableDeclaration>) {
        const { declarations } = path.node

        // 获取申明中的变量 以及 对应的值
        for (let i = 0; i < declarations.length; i++) {
          const { id, init } = declarations[i] as types.VariableDeclarator
          identify2ValArr[id.name] = init.value
        }
      }
    }
  }
}
